Scrawl.php
<?php
namespace Tlf;
class Scrawl {
use Scrawl\Commands;
protected $extensions;
protected $configs;
public $dir;
protected $outputs = [];
public function error($header, $message){
echo "\033[0;31m$header:\033[0m $message\033[0;31m...\033[0m\n";
}
/**
*
* @param $project_dir root dir of the project
* @param $configs array of configurations
*/
public function __construct(string $project_dir, array $configs=[]){
$this->dir = $project_dir;
//arrayify configs
$copy = $configs;
foreach ($copy as $key=>$opt){
if (!is_array($opt)){
$configs[$key] = [$opt];
}
}
//perform autoload (even though this should just be done through composer)
foreach ($configs['autoload']['classmap']??[] as $dir){
\Tlf\Scrawl\Utility::autoload($project_dir.'/'.$dir);
}
$this->configs = $configs;
}
public function add_standard_extensions(){
$this->addExtension(new Scrawl\Ext\DefaultExt\CopyReadme($this));
$this->addExtension(new Scrawl\Ext\DefaultExt\ExportDocBlock($this));
$this->addExtension(new Scrawl\Ext\DefaultExt\ExportStartEnd($this));
$this->addExtension(new Scrawl\Ext\DefaultExt\WriteExportList($this));
$this->addExtension(new Scrawl\Ext\DefaultExt\MarkdownVerbs($this));
$this->addExtension(new Scrawl\Ext\MdVerb\SimpleVerbs($this));
$this->addExtension(new Scrawl\Ext\MdVerb\Ast($this));
$this->addExtension(new Scrawl\Ext\Lang\Php($this));
// $this->addExtension(new Scrawl\Ext\Lang\Bash($this));
}
public function pathToRootFrom($configuredDirectory){
$relPath = $this->getConfig('dir.'.$configuredDirectory);
if ($relPath===null) return null;
$relPath = $relPath[0];
$relPath = str_replace('\\','/',$relPath);
$parts = explode('/', $relPath);
$retRelPath = '';
foreach ($parts as $p){
$retRelPath .= '../';
}
return $retRelPath;
}
public function getConfig($key){
return $this->configs[$key] ?? null;
}
/**
* Get an array of groups this extensions is in
*/
public function get_extension_groups(object $extension): array{
$groups = [];
$interfaces = class_implements($extension);
$lookFor = 'Tlf\\Scrawl\\ExtensionType';
foreach ($interfaces as $i){
if (substr($i, 0, strlen($lookFor)) !== $lookFor){
continue;
}
$group =
strtolower(
substr(
$i,
strlen($lookFor)+1,
-strlen('Interface')
)
);
$groups[] = $group;
}
return $groups;
}
public function addExtension(object $extension){
$groups = $this->get_extension_groups($extension);
foreach ($groups as $g){
$this->extensions[$g][] = $extension;
}
}
public function getExtensions($group){
return $this->extensions[$group];
}
public function addOutput(string $group, string $key, $content){
$existing = $this->output[$group][$key] ?? null;
if ($existing!==null)throw new \Exception("Output for '{$group}', '{$key}' has already been set...");
$this->outputs[$group][$key] = $content;
}
public function setOutput(string $group, string $key, $content){
$this->outputs[$group][$key] = $content;
}
public function getOutput(string $group, string $key) {
return $this->outputs[$group][$key] ?? null;
}
public function getOutputs(?string $group=null): ?array{
if ($group===null)return $this->outputs;
return $this->outputs[$group] ?? null;
}
public function extCall(string $group, ?string $methodName, ...$args){
$rets = [];
foreach ($this->getExtensions($group) as $ext){
if (is_object($ext)){
$rets[] = $ext->$methodName(...$args);
} else if (is_callable($ext)){
$rets[] = $ext(...$args);
}
}
return $rets;
}
public function getFilesToDocument(){
$root = $this->dir;
$codeDirs = $this->configs['dir.code'];
$codeExts = $this->configs['file.code.ext'];
$files = [];
foreach ($codeDirs as $d){
$newFiles = Scrawl\Utility::allFilesFromDir($root, $d, $codeExts);
$files = [...$files, ...$newFiles];
}
return $files;
}
public function getTemplateFiles(){
$root = $this->dir;
$templateDirs = $this->configs['dir.template'];
$templateExts = $this->configs['file.template.ext'];
$files = [];
foreach ($templateDirs as $td){
$newFiles = Scrawl\Utility::allFilesFromDir($root.'/'.$td, '', $templateExts);
$files = [...$files, ...$newFiles];
}
return $files;
}
public function writeFile(Scrawl\File $outputFile, $dryRun=false){
$relPath = $outputFile->relPath;
$nb = strlen($outputFile->content());
echo "Write $nb chars to $relPath\n";
if ($dryRun){
return;
}
$outputFile->write();
}
public function loadTemplate($ext, $templateName, array $argList){
$template = __DIR__.'/Template/'.$templateName.'.php';
if (!is_file($template))$template = __DIR__.'/Template/'.$templateName.'.md.php';
if (!is_file($template))$template = $this->dir.'/'.$this->configs['dir.template_files'][0].'/'.$templateName.'.md.php';
if (!is_file($template))$template = $this->dir.'/'.$this->configs['dir.template_files'][0].'/'.$templateName.'.php';
if (!is_file($template)){
echo "\nError: Template '$templateName' not found.\n";
return "Template '$templateName' not found.";
}
$argv = array_values($argList);
$scrawl = $this;
array_unshift($argv, $_SERVER['argv'][0]??null);
ob_start();
require($template);
$final = ob_get_clean();
return trim($final);
}
}